package com.apesource.project02.service;

import com.alibaba.fastjson.JSON;
import com.apesource.project02.mapper.IMarathonEventsMapper;
import com.apesource.project02.mapper.IRegistrationsMapper;
import com.apesource.project02.mapper.IUserMapper;
import com.apesource.project02.pojo.MarathonEvent;
import com.apesource.project02.pojo.Registration;
import com.apesource.project02.pojo.User;
import com.apesource.project02.util.ResponseEntity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @version 1.0
 * @auther:暮雪
 * @date:2025/9/18
 */

@Service
public class RegistrationServiceImp extends ServiceImpl<IRegistrationsMapper, Registration> implements IRegistrationService {

    @Autowired
    private IRegistrationsMapper registrationsMapper;

    @Autowired
    private IMarathonEventsMapper marathonEventsMapper;


    @Autowired
    private RedisTemplate jsonRedisTemplate;

    @Autowired
    private IUserServer userServer;

    @Autowired
    private IMarathonEventService marathonEventService;

    @Override
    public List<Registration> getRegistrationById(int id) {
        return Collections.emptyList();
    }

    //统计所有报名该赛事的人员
    @Override
    public int countRegistration(int eventId) {
        List<Registration> registrations=new ArrayList<>();
        Set<String> keys = jsonRedisTemplate.keys("registration:id:*");
        if (keys == null || keys.size() == 0) {
            LambdaQueryWrapper<Registration> queryWrapper2 = new LambdaQueryWrapper<>();
            queryWrapper2.eq(Registration::getEventId, eventId);
            registrations = registrationsMapper.selectList(queryWrapper2);
            for (Registration registration1 : registrations) {
                jsonRedisTemplate.opsForValue().set("registration:id:" + registration1.getRegistrationId(), JSON.toJSONString(registration1));
            }
        }else {
            List<Registration> registrationRedisList=new ArrayList<>();
            for (String key : keys) {
                Object registrationJson = jsonRedisTemplate.opsForValue().get(key);
                registrationRedisList.add(JSON.parseObject(registrationJson.toString(), Registration.class));
            }
            registrations=registrationRedisList.stream().filter(registration1 -> registration1.getEventId()==eventId).collect(Collectors.toList());
        }
        return registrations.size();
    }

    @Override
    public ResponseEntity<Registration> registerMarathonEvent(Registration registration) {
        registration.setRegistrationTime(new Date());
        ResponseEntity<Registration> responseEntity = new ResponseEntity<>();


        //报名人员是否存在
        User user = userServer.findUserById(registration.getUserId()).getData();
        if (user == null) {
            responseEntity.setStatusCode(404);
            responseEntity.setMessage("There is no such athlete");
            return responseEntity;
        }

        //该人员是否已经报名
        List<Registration> registrationList;
        Set<String> registrationIds = jsonRedisTemplate.keys("registration:id:*");
        if (registrationIds == null || registrationIds.size() == 0) {
            LambdaQueryWrapper<Registration> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Registration::getUserId, user.getUserId());
            queryWrapper.eq(Registration::getEventId, registration.getEventId());
            registrationList = registrationsMapper.selectList(queryWrapper);
            for (Registration registration1 : registrationList) {
                jsonRedisTemplate.opsForValue().set("registration:id:" + registration1.getRegistrationId(), JSON.toJSONString(registration1));
            }
        } else {
            List<Registration> registrationRedisList = new ArrayList<>();
            for (String registrationId : registrationIds) {
                Object registrationJson = jsonRedisTemplate.opsForValue().get(registrationId);
                if (registrationJson != null)
                    registrationRedisList.add(JSON.parseObject(registrationJson.toString(), Registration.class));
            }
            registrationList = registrationRedisList.stream().filter(registration1 -> registration1.getEventId()==registration.getEventId()).filter(registration1 -> registration1.getUserId()==registration.getUserId()).collect(Collectors.toList());
        }
        if (registrationList.size() > 0) {
            responseEntity.setStatusCode(409);
            responseEntity.setMessage("Already registered");
            return responseEntity;
        }

        //赛事是否存在
        MarathonEvent marathonEvent=marathonEventService.getMarathonEventById(registration.getEventId()).getData();
        if (marathonEvent == null) {
            responseEntity.setStatusCode(404);
            responseEntity.setData(null);
            responseEntity.setMessage("Not found this marathon event");
            return responseEntity;
        }

        //通过赛事ID查询，当前报名时间在不在报名时间范围内
        if (marathonEvent.getRegistrationStart().after(new Date()) ||
                marathonEvent.getRegistrationEnd().before(new Date())) {
            responseEntity.setStatusCode(400);
            responseEntity.setData(null);
            responseEntity.setMessage("Registration has not started or has ended");
            return responseEntity;
        }

        //判断赛事最大报名人员剩余多少
        if (marathonEvent.getMaxParticipants() - countRegistration(registration.getEventId()) <= 0) {
            responseEntity.setStatusCode(400);
            responseEntity.setData(null);
            responseEntity.setMessage("The number of registrants has reached the limit");
            return responseEntity;
        }

        //3.报名，新增报名记录表数据
        registration.setStatus("已报名");
        int res=registrationsMapper.insert(registration);
        if (res > 0) {
            jsonRedisTemplate.opsForValue().set("registration:id:" + registration.getRegistrationId(), JSON.toJSONString(registration));
        }
        responseEntity.setStatusCode(201);
        responseEntity.setData(registration);
        responseEntity.setMessage("success");
        return responseEntity;
    }
}
